package com.platform.usercenter.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.platform.common.core.domain.entity.SysRole;
import com.platform.common.core.domain.entity.SysUser;
import com.platform.common.core.domain.model.DataPermissionDTO;
import com.platform.common.core.domain.model.PermissionGroupDTO;
import com.platform.usercenter.domain.SysOrganization;
import com.platform.usercenter.domain.dto.SelectOptionDTO;
import com.platform.usercenter.domain.vo.SysMenuPermissionVO;
import com.platform.usercenter.service.ISysMenuService;
import com.platform.usercenter.service.ISysOrganizationService;
import com.platform.usercenter.service.ISysPermissionService;
import com.platform.usercenter.service.ISysRoleService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户权限处理
 *
 * @author
 */
@Service
public class SysPermissionServiceImpl implements ISysPermissionService {
    @Resource
    private ISysRoleService roleService;

    @Resource
    private ISysMenuService menuService;

    @Resource
    private ISysOrganizationService iSysOrganizationService;

    /**
     * 获取角色数据权限
     *
     * @param user 用户Id
     * @return 角色权限信息
     */
    @Override
    public Set<String> getRolePermission(SysUser user) {
        Set<String> roles = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            roles.add("admin");
        } else {
            roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
        }
        return roles;
    }

    /**
     * 获取角色组织数据权限
     *
     * @param user 用户id, 组织id
     * @return 角色权限信息
     */
    @Override
    public Set<String> getRoleDeptPermission(SysUser user, Long orgId) {
        Set<String> roles = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            roles.add("admin");
        } else {
            roles.addAll(roleService.selectRolePermissionByUserIdAndDeptId(user.getUserId(), orgId));
        }
        return roles;
    }

    @Override
    public List<SysOrganization> getOrgIdPermission(SysUser user) {
        List<SysOrganization> organizationList = new ArrayList<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            organizationList = iSysOrganizationService.selectSysOrganizationList(new SysOrganization());
            //按照排序字段正序排
            organizationList.stream()
                    .sorted(Comparator.comparing(SysOrganization::getOrderNum).reversed())
                    .collect(Collectors.toList());
        } else {
            organizationList.addAll(iSysOrganizationService.selectSysOrganizationListByUserId(user.getUserId()));
        }
        return organizationList;
    }

    /**
     * 获取菜单数据权限
     *
     * @param user 用户Id
     * @return 菜单权限信息
     */
    @Override
    public Set<String> getMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            perms.add("*:*:*");
        } else {
            List<SysRole> roles = user.getRoles();
            if (!roles.isEmpty()) {
                // 多角色设置permissions属性，以便数据权限匹配权限
                for (SysRole role : roles) {
                    Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
                    role.setPermissions(rolePerms);
                    perms.addAll(rolePerms);
                }
            }
        }
        return perms;
    }

    /**
     * 获取菜单数据权限
     *
     * @param user 用户Id
     * @return 菜单权限信息
     */
    @Override
    public List<DataPermissionDTO> getDataPermissions(SysUser user) {

        List<DataPermissionDTO> dtoList = new ArrayList<>();
        List<SysMenuPermissionVO> permissionVOS;
        // 管理员拥有所有权限
        if (user.isAdmin())
        {
            permissionVOS=menuService.getDataPermissionsAll(user);
        }
        else
        {
            permissionVOS = menuService.getDataPermissions(user);
        }
        if(CollectionUtils.isNotEmpty(permissionVOS)){
            Map<String,List<SysMenuPermissionVO>> listMap = permissionVOS.stream().collect(Collectors.groupingBy(v->v.getFunctionId().toString()));
            for (String key : listMap.keySet()){
                List<SysMenuPermissionVO> permissionVOList = listMap.get(key);
                DataPermissionDTO permissionDTO = new DataPermissionDTO();
                permissionDTO.setFunctionId(permissionVOList.get(0).getFunctionId());
                permissionDTO.setFunctionCode(permissionVOList.get(0).getFunctionCode());
                permissionDTO.setDataPermissionUrl(permissionVOList.get(0).getDataPermissionUrl());
                List<PermissionGroupDTO> dataPermissions = new ArrayList<>();
                //key值进行处理
                Map<String, List<SelectOptionDTO>> keyValueMap = new HashMap<>();
                for (SysMenuPermissionVO permissionVO : permissionVOList){
                    if(StringUtils.isNotEmpty(permissionVO.getPermissionValue())){
                        JSONArray jsonArray = JSONObject.parseArray(permissionVO.getPermissionValue());
                        if(ObjectUtil.isNotEmpty(jsonArray)){
                            List<SelectOptionDTO> optionDTOS = jsonArray.toJavaList(SelectOptionDTO.class);
                            if(CollectionUtils.isNotEmpty(optionDTOS)){
                                //不包含key
                                if (!keyValueMap.containsKey(permissionVO.getPermissionKey())) {
                                    keyValueMap.put(permissionVO.getPermissionKey(),optionDTOS);

                                }else{
                                    List<SelectOptionDTO> oldOptions=keyValueMap.get(permissionVO.getPermissionKey());
                                    oldOptions.addAll(optionDTOS);
                                    keyValueMap.put(permissionVO.getPermissionKey(),oldOptions);
                                }
                            }
                        }
                    }
                }

                for (Map.Entry<String, List<SelectOptionDTO>> value : keyValueMap.entrySet()) {
                    PermissionGroupDTO groupDTO  = new PermissionGroupDTO();
                    groupDTO.setPermissionKey(value.getKey());
                    StringBuilder valueStr = new StringBuilder();
                    if(CollectionUtils.isNotEmpty(value.getValue())){
                        for(SelectOptionDTO dto : value.getValue()){
                            if(ObjectUtils.isEmpty(valueStr)){
                                valueStr.append(dto.getValue());
                            }else {
                                if(valueStr.indexOf(dto.getValue()) == -1){
                                    valueStr.append(","+dto.getValue());
                                }
                            }
                        }
                    }
                    groupDTO.setPermissionValue(valueStr.toString());
                    dataPermissions.add(groupDTO);
                }
                permissionDTO.setDataPermissions(dataPermissions);

                dtoList.add(permissionDTO);
            }
        }
        return dtoList;
    }

}
